
#include "Box3.h"
#include <algorithm>
#include <limits>

namespace soft_renderer
{
	Box3::Box3()
	{
		min.set(std::numeric_limits<double>::max(),
			std::numeric_limits<double>::max(),
			std::numeric_limits<double>::max());
		max.set(-std::numeric_limits<double>::max(),
			-std::numeric_limits<double>::max(),
			-std::numeric_limits<double>::max());
	}

	void Box3::setEmpty()
	{
		min.set(std::numeric_limits<double>::max(),
			std::numeric_limits<double>::max(),
			std::numeric_limits<double>::max());
		max.set(-std::numeric_limits<double>::max(),
			-std::numeric_limits<double>::max(),
			-std::numeric_limits<double>::max());
	}

	void Box3::expandByPoint(Vector3 p)
	{
		min.setX(std::min(p.x(), min.x()));
		min.setY(std::min(p.y(), min.y()));
		min.setZ(std::min(p.z(), min.z()));

		max.setX(std::max(p.x(), max.x()));
		max.setY(std::max(p.y(), max.y()));
		max.setZ(std::max(p.z(), max.z()));
	}

	void Box3::expandByPoint(double x, double y, double z)
	{
		min.setX(std::min(x, min.x()));
		min.setY(std::min(y, min.y()));
		min.setZ(std::min(z, min.z()));

		max.setX(std::max(x, max.x()));
		max.setY(std::max(y, max.y()));
		max.setZ(std::max(z, max.z()));
	}

	Vector3 Box3::getSize()
	{
		Vector3 size;
		size.subVectors(max, min);
		return size;
	}

	Vector3 Box3::getCenter()
	{
		return Vector3((min.x() + max.x()) * 0.5,
			(min.y() + max.y()) * 0.5,
			(min.z() + max.z()) * 0.5);
	}

	//bool Box3::intersectsPlane(Plane plane)
	//{
	//	// We compute the minimum and maximum dot product values. If those values
	//	// are on the same side (back or front) of the plane, then there is no intersection.
	//
	//	double min, max;
	//
	//	Vector3 pn = plane.Normal();
	//
	//	if (pn.X() > 0)
	//	{
	//		min = pn.X() * this->min.X();
	//		max = pn.X() * this->max.X();
	//	}
	//	else
	//	{
	//		min = pn.X() * this->max.X();
	//		max = pn.X() * this->min.X();
	//	}
	//
	//	if (pn.Y() > 0)
	//	{
	//		min += pn.Y() * this->min.Y();
	//		max += pn.Y() * this->max.Y();
	//	}
	//	else
	//	{
	//		min += pn.Y() * this->max.Y();
	//		max += pn.Y() * this->min.Y();
	//	}
	//
	//	if (pn.Z() > 0)
	//	{
	//		min += pn.Z() * this->min.Z();
	//		max += pn.Z() * this->max.Z();
	//	}
	//	else
	//	{
	//		min += pn.Z() * this->max.Z();
	//		max += pn.Z() * this->min.Z();
	//	}
	//
	//	return (min <= -plane.Constant() && max >= -plane.Constant());
	//}

}
